home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
drdobbs
/
1991
/
10
/
embedcp.asc
< prev
next >
Wrap
Text File
|
1991-09-10
|
6KB
|
203 lines
_C++ FOR EMBEDDED SYSTEMS_
by Stuart G. Phillips and Kevin J. Rowett
[LISTING ONE]
// MIOTDREM
// --------
// Copyright (c) 1991, Stuart G. Phillips. All rights reserved.
// Permission is granted for non-commercial use of this software.
// You are expressly prohibited from selling this software in any form,
// distributing it with another product, or removing this notice.
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
// PURPOSE.
// This module contains the main() for the MIO version of TDREMOTE. The
// module is primarily responsible for initialization; TDREMOTE functions
// are handled in other modules.
#include "mio.h"
#include "8530.h"
#include "miotdr.h"
#ifdef SERIAL_DEBUG
// Communication region used to deposit status information about the
// programs progress etc in the shared memory window.
struct comm_region { unsigned short status;
unsigned short scc_status;
unsigned short scc_special;
unsigned short int_cnt;
unsigned short rx_cnt;
unsigned short tx_cnt;
unsigned char command;
};
#endif
struct relo_creg { unsigned short offset;
unsigned short segment;
unsigned short count;
unsigned char command;
};
// Command values for RELO.LOD
#define RELO_NULL 0x00
#define RELO_COPYTO 0x01
#define RELO_COPYFROM 0x02
#define RELO_EXIT 0x03
// Magic number signifying presence of "RELO" support
#define RELO_MAGIC 0x5a41
extern void tdr_processor();
static void relo_lod();
#ifdef SERIAL_DEBUG
static struct comm_region *creg = (struct comm_region *)0x80;
#endif
// Globals
unsigned char rx_buffer[BUFLEN],
tx_buffer[BUFLEN];
unsigned _stklen = 512U;
void main()
{
unsigned char data,val;
unsigned short i;
disable();
// Enable ICU in the V40 peripheral select register
data = inportb(OPSEL);
outportb(OPSEL,data|ICU);
data = inportb(OPSEL);
#ifdef SERIAL_DEBUG
creg->status = data;
#endif
/* Initialize the ICU */
outportb(IULA,ICUBASE); // set base address */
outportb(IMDW,IIW1|IIW4NR|IEM|IET); // no IIW4, extended mode,
// edge triggered
//
outportb(IMKW,IVEC); // Set vector base for PIC/
outportb(IMKW,SI7); // IRQ7 is slave
outportb(IMKW,0xff); // Mask off all interrupts
relo_lod(); // Provide relocation support
// to MIOLOAD
#ifdef SERIAL_DEBUG
creg->status = 0;
creg->scc_status = 0;
creg->scc_special = 0;
creg->int_cnt = 0;
creg->rx_cnt = 0;
creg->tx_cnt = 0;
creg->command = 0xff;
#endif
comm_init();
tdr_processor();
/*NOTREACHED*/
}
static void relo_lod()
{
struct relo_creg *creg = (struct relo_creg *) 0x80;
unsigned short *magic = (unsigned short *) 0x88;
unsigned char *go = (unsigned char *) 0x9f;
unsigned char *swin, *p;
unsigned short i, relo_done = 0;
// Initialize command field in communication region
creg->command = 0xff;
// Implant magic number so that MIOLOAD knows we're up and running
*magic = RELO_MAGIC;
while (!relo_done){
// Wait for command value to change from 0xff
while (creg->command == 0xff) ;
switch(creg->command){
case RELO_COPYTO:
p = (unsigned char *)(((long)creg->segment << 16) +
(long)creg->offset);
swin = (unsigned char *) 0x100;
for(i = creg->count; i != 0; i--)
*p++ = *swin++;
creg->command = 0xff;
break;
case RELO_COPYFROM:
p = (unsigned char *)(((long)creg->segment << 16) +
(long)creg->offset);
swin = (unsigned char *) 0x100;
for(i = creg->count; i != 0; i--)
*swin++ = *p++;
creg->command = 0xff;
break;
case RELO_EXIT:
creg->command = 0xff;
relo_done = 1;
break;
default:
creg->command = 0xff;
break;
}
}
// Clear our magic marker and then reset go flag to 0xf4 (halt) code.
// Wait for MIOLOAD to set this to 0x90 to indicate we should continue.
*magic = 0;
*go = 0xf4;
while (*go != 0x90) ;
}
Figure 1: Format of EXE file header
struct EXEHDR {
unsigned short magic; // EXE file if 0x5a4d
unsigned short nbytes; // Size of last page in bytes
unsigned short npages; // Size of image in pages
// 1 page = 512 bytes
unsigned short nreloc; // Number of relocation items
unsigned short hdrsize; // Size of EXE header
unsigned short endmin; // Minimum memory
unsigned short hilo_flag;
unsigned short ss_offset; // Stack segment offset
unsigned short val_sp; // Initial value for SP
unsigned short chksum;
unsigned short val_ip; // Initial value for IP
unsigned short cs_offset; // Code segment offset
unsigned short rel_offset; // Offset of relocation items
unsigned short ovl_num; // Overlay number
};
Figure 2: Format of LOD file header
struct LODHDR {
unsigned short magic; // LOD file if 0x4655
unsigned short version; // Version id of LOD header
unsigned short val_offset; // Initial value for IP
unsigned short val_seg; // initial value for CS
long timestamp; // DOS time stamp of orig. EXE file
long image_size; // Image size in bytes
};